<template>
    <div>
        <el-button
            class="button-space"
            @click="addView(null,'add')"
            type="success"
            size="small"
        >添加顶级菜单
        </el-button>
        <el-table :data="data.menus" border style="width: 100%;margin-top: 10px" v-loading="data.loading"
                  ref="lazyTableRef"
                  lazy
                  element-loading-text="拼命加载中"
                  :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
                  row-key="uuid" :load="loadChildren">
            <el-table-column fixed prop="name" label="菜单名称" align="center" width="150px"/>
            <el-table-column prop="path" label="菜单路径" align="center" width="150px"/>
            <el-table-column prop="componentName" label="组件名称" align="center" width="180"/>
            <el-table-column prop="icon" label="图标" align="center" width="180"/>
            <el-table-column prop="isMenu" label="是否是菜单" align="center" width="180">
                <template #default="scope">
                    <el-tag
                        :type="scope.row.isMenu === true ? 'success' : 'primary'"
                        disable-transitions
                    >{{ scope.row.isMenu === true ? "菜单" : "按钮" }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="isMenu" label="是否是路由" align="center" width="180">
                <template #default="scope">
                    <el-tag
                        :type="scope.row.isRouter === true ? 'success' : 'primary'"
                        disable-transitions
                    >{{ scope.row.isRouter === true ? "是" : "否" }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="isHidden" label="是否隐藏" align="center" width="180">
                <template #default="scope">
                    <el-tag
                        :type="scope.row.isHidden === true ? 'success' : 'primary'"
                        disable-transitions
                    >{{ scope.row.isHidden === true ? "是" : "否" }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="sort" label="排序" width="180" align="center"/>
            <el-table-column prop="createTime" label="创建时间" width="180" align="center"/>
            <el-table-column prop="updateTime" label="更新时间" width="180" align="center"/>
            <el-table-column fixed="right" label="操作" width="350" align="center">
                <template #default="scope">
                    <el-button
                        class="button-space"
                        @click="addView(scope.row,'add')"
                        type="success"
                        size="small"
                    >添加下级
                    </el-button>
                    <el-button
                        class="button-space"
                        @click="moveUpMenu(scope.row)"
                        type="primary"
                        size="small"
                    >上移
                    </el-button>
                    <el-button
                        class="button-space"
                        @click="moveDownMenu(scope.row)"
                        type="warning"
                        size="small"
                    >下移
                    </el-button>
                    <el-button
                        class="button-space"
                        @click="addView(scope.row,'edit')"
                        type="info"
                        size="small"
                    >编辑
                    </el-button>
                    <el-button
                        class="button-space"
                        @click="deleteMenu(scope.row)"
                        type="danger"
                        size="small"
                    >删除
                    </el-button>
                </template>
            </el-table-column>
        </el-table>
        <!-- 添加或修改菜单 -->
        <el-drawer v-model="data.menuAddOrUpdateDisable" :title="data.title">
            <el-form :model="menuAddOrUpdateData" :rules="rules" ref="addFormRef">
                <el-form-item label="上级菜单" label-width="130px">
                    <el-input v-model="data.parentMenuName" autocomplete="off" disabled/>
                </el-form-item>
                <el-form-item label="是否是路由" label-width="130px" prop="isRouter">
                    <el-select
                        clearable
                        v-model="menuAddOrUpdateData.isRouter"
                        placeholder="请选择是否是路由"
                        @change="selectIsRouter"
                    >
                        <el-option label="是" :value="true"/>
                        <el-option label="否" :value="false"/>
                    </el-select>
                </el-form-item>
                <el-form-item label="名称" label-width="130px" prop="name">
                    <el-input v-model="menuAddOrUpdateData.name" autocomplete="off"/>
                </el-form-item>
                <el-form-item label="路径" label-width="130px" prop="path">
                    <el-input v-model="menuAddOrUpdateData.path" autocomplete="off"/>
                </el-form-item>
                <el-form-item label="图标" label-width="130px" prop="icon">
                    <el-input v-model="menuAddOrUpdateData.icon" autocomplete="off"/>
                </el-form-item>
                <el-form-item label="组件名称" label-width="130px" prop="componentName" v-if="data.isRouter">
                    <el-input v-model="menuAddOrUpdateData.componentName" autocomplete="off"/>
                </el-form-item>
                <el-form-item label="是否是菜单" label-width="130px" prop="isMenu">
                    <el-select
                        clearable
                        v-model="menuAddOrUpdateData.isMenu"
                        placeholder="请选择"
                    >
                        <el-option label="菜单" :value="true"/>
                        <el-option label="按钮" :value="false"/>
                    </el-select>
                </el-form-item>
                <el-form-item label="是否隐藏" label-width="130px" prop="isHidden">
                    <el-select
                        clearable
                        v-model="menuAddOrUpdateData.isHidden"
                        placeholder="请选择是否隐藏"
                    >
                        <el-option label="是" :value="true"/>
                        <el-option label="否" :value="false"/>
                    </el-select>
                </el-form-item>
                <el-form-item label-width="130px">
                    <el-button @click="data.menuAddOrUpdateDisable = false">取 消</el-button>
                    <el-button type="primary" @click="addOrUpdateMenu">确认</el-button>
                </el-form-item>
            </el-form>
        </el-drawer>
    </div>
</template>

<script>
import {reactive, onMounted, ref} from "vue";
import {listByParentUuid, addChildren, deleted, add, update, moveUp, moveDown} from "@/api/menu/menu";
import {ElMessage, ElMessageBox} from "element-plus";

export default {
    setup() {
        const data = reactive({
            menus: [],
            defaultParentUuid: '0',
            title: '',
            menuAddOrUpdateDisable: false,
            parentMenuName: '',
            updateMenuUuid: '',
            currentMenu: '',
            isRouter: false,
            map: new Map()
        })
        const menuAddOrUpdateData = reactive({
            name: '',
            path: '',
            icon: '',
            componentName: '',
            isMenu: '',
            isRouter: '',
            isHidden: ''
        })
        const rules = reactive({
            name: [
                {
                    required: true,
                    message: "请输入菜单名称",
                    trigger: "blur",
                },
            ],
            path: [
                {
                    required: true,
                    message: "请输入菜单路径",
                    trigger: "blur",
                },
            ],
            icon: [
                {
                    required: true,
                    message: "请输入菜单图标",
                    trigger: "blur",
                },
            ],
            componentName: [
                {
                    required: true,
                    message: "请输入组件名称",
                    trigger: "blur",
                },
            ],
            isMenu: [
                {
                    required: true,
                    message: "请选择是否是菜单",
                    trigger: "blur",
                },
            ],
            isRouter: [
                {
                    required: true,
                    message: "请选择是否是路由",
                    trigger: "blur",
                },
            ],
            isHidden: [
                {
                    required: true,
                    message: "请选择是否隐藏",
                    trigger: "blur",
                },
            ]
        })
        const addFormRef = ref(null)
        const lazyTableRef = ref(null)
        /**
         * 获取父级菜单
         */
        const listMenuByParentUuid = () => {
            listByParentUuid(data.defaultParentUuid).then(res => {
                data.menus = res.data
                data.menus.forEach(menu => {
                    menu.children = []
                })
            })
        }
        /**
         * 获取子集菜单
         */
        const loadChildren = (row, treeNode, resolve) => {
            data.map.set(row.uuid, {row, treeNode, resolve})
            listByParentUuid(row.uuid).then(res => {
                res.data.forEach(menu => {
                    menu.children = []
                })
                resolve(res.data)
            })
        }
        const addView = (row, type) => {
            if (type === 'add') {
                data.title = '添加菜单'
                reset();
                if (row != null) {
                    data.defaultParentUuid = row.uuid
                    data.currentMenu = row
                    data.parentMenuName = row.parentMenuName === '' ? row.name : row.parentMenuName
                }
            } else {
                data.title = '编辑菜单'
                data.updateMenuUuid = row.uuid
                data.parentMenuName = row.parentMenuName
                data.currentMenu = row
                data.isRouter = row.isRouter
                menuAddOrUpdateData.name = row.name
                menuAddOrUpdateData.path = row.path
                menuAddOrUpdateData.icon = row.icon
                menuAddOrUpdateData.componentName = row.componentName
                menuAddOrUpdateData.isMenu = row.isMenu
                menuAddOrUpdateData.isRouter = row.isRouter
                menuAddOrUpdateData.isHidden = row.isHidden
            }
            data.menuAddOrUpdateDisable = true
        }
        /**
         * 添加或修改菜单
         */
        const addOrUpdateMenu = () => {
            addFormRef.value.validate((valid) => {
                if (!valid) {
                    return false
                }
                if (data.updateMenuUuid) {
                    // 编辑
                    update(menuAddOrUpdateData, data.updateMenuUuid).then(() => {
                        ElMessage({
                            message: '修改成功',
                            type: 'success',
                        })
                        data.menuAddOrUpdateDisable = false
                        data.defaultParentUuid = '0'
                        data.updateMenuUuid = ''
                        data.currentMenu.name = menuAddOrUpdateData.name
                        data.currentMenu.path = menuAddOrUpdateData.path
                        data.currentMenu.componentName = menuAddOrUpdateData.componentName
                        data.currentMenu.icon = menuAddOrUpdateData.icon
                        data.currentMenu.isMenu = menuAddOrUpdateData.isMenu
                        data.currentMenu.isRouter = menuAddOrUpdateData.isRouter
                        data.currentMenu.isHidden = menuAddOrUpdateData.isHidden
                    })
                } else {
                    const store = lazyTableRef.value.store
                    if (data.currentMenu !== '') {
                        let childList = store.states.lazyTreeNodeMap.value[data.defaultParentUuid]
                        // 添加
                        addChildren(menuAddOrUpdateData, data.defaultParentUuid).then(res => {
                            ElMessage({
                                message: '添加成功',
                                type: 'success',
                            })
                            if (childList === undefined || childList.length <= 0) {
                                data.currentMenu.children.unshift(res.data)
                                data.currentMenu.hasChildren = true
                            } else {
                                childList.unshift(res.data)
                            }
                            data.menuAddOrUpdateDisable = false
                            data.defaultParentUuid = '0'
                        })
                    } else {
                        add(menuAddOrUpdateData).then(() => {
                            ElMessage({
                                message: '添加成功',
                                type: 'success',
                            })
                            data.menuAddOrUpdateDisable = false
                            data.defaultParentUuid = '0'
                            listMenuByParentUuid()
                        })
                    }
                }
            })
        }
        /**
         * 删除菜单
         * @param row
         */
        const deleteMenu = (row) => {
            const store = lazyTableRef.value.store
            if (row.hasChildren) {
                ElMessageBox.confirm(
                    '该菜单是父级菜单，是否一键删除子集菜单？',
                    '删除提示',
                    {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        type: 'warning',
                    }
                )
                    .then(() => {
                        // 是父级节点
                        data.menus = store.states.data.value
                        const childIndex = data.menus.findIndex(item => item.uuid === row.uuid)
                        data.menus.splice(childIndex, 1)
                        deleted(row.uuid).then(() => {
                            ElMessage({
                                message: '删除成功',
                                type: 'success',
                            })
                        })
                    })
                    .catch(() => {
                        ElMessage({
                            type: 'info',
                            message: '取消删除',
                        })
                    })
            } else {
                // 不是父级节点
                const childList = store.states.lazyTreeNodeMap.value[row.parentUuid]
                if (childList === undefined || childList.length <= 0) {
                    data.menus = store.states.data.value
                    const deleteIndex = data.menus.findIndex(item => item.uuid === row.uuid)
                    data.menus.splice(deleteIndex, 1)
                } else {
                    //删除
                    const delIndex = childList.findIndex(item => row.uuid === item.uuid)
                    childList.splice(delIndex, 1)
                    if (childList.length <= 0) {
                        const parentMenu = data.menus.filter(item => item.uuid === row.parentUuid)[0]
                        parentMenu.hasChildren = false
                        parentMenu.children = []
                    }
                }
                deleted(row.uuid).then(() => {
                    ElMessage({
                        message: '删除成功',
                        type: 'success',
                    })
                })
            }
        }
        /**
         * 重置添加数据
         */
        const reset = () => {
            menuAddOrUpdateData.name = ''
            menuAddOrUpdateData.icon = ''
            menuAddOrUpdateData.path = ''
            menuAddOrUpdateData.isMenu = ''
            menuAddOrUpdateData.componentName = ''
            menuAddOrUpdateData.isRouter = ''
            menuAddOrUpdateData.isHidden = ''
        }
        /**
         * 选择是否是路由
         * @param value
         */
        const selectIsRouter = (value) => {
            data.isRouter = value
        }
        /**
         * 上移菜单
         * @param menuRow
         */
        const moveUpMenu = (menuRow) => {
            moveUp(menuRow.uuid).then(() => {
                ElMessage({
                    message: '上移成功',
                    type: 'success',
                })
                data.defaultParentUuid = '0'
                if (menuRow.parentUuid !== '0') {
                    const {row, treeNode, resolve} = data.map.get(menuRow.parentUuid)
                    loadChildren(row, treeNode, resolve)
                } else {
                    listMenuByParentUuid()
                }
            })
        }
        /**
         * 下移菜单
         * @param menuRow
         */
        const moveDownMenu = (menuRow) => {
            moveDown(menuRow.uuid).then(() => {
                ElMessage({
                    message: '下移成功',
                    type: 'success',
                })
                data.defaultParentUuid = '0'
                if (menuRow.parentUuid !== '0') {
                    const {row, treeNode, resolve} = data.map.get(menuRow.parentUuid)
                    loadChildren(row, treeNode, resolve)
                } else {
                    listMenuByParentUuid()
                }
            })
        }
        onMounted(() => {
            listMenuByParentUuid()
        })
        return {
            data,
            menuAddOrUpdateData,
            rules,
            addFormRef,
            lazyTableRef,
            loadChildren,
            addView,
            addOrUpdateMenu,
            deleteMenu,
            selectIsRouter,
            moveUpMenu,
            moveDownMenu
        }
    }
}
</script>